#ifndef __TREE_H__
#define __TREE_H__

typedef struct Tree_t Tree;
typedef struct TreeIter_t* TreeIter;

/*  Create new binary search tree. The arrangement of the tree is done according to less comparing function     *
 *  supplied. The less function has to have the followed prototype, and return 1 if data1 is smaller, else 0.   *
 *  Return value is Tree pointer on failure 0, and prints to stderr. Failure can appear if allocation failed.   *
 *  example for less function:

    typedef struct Person
    {
        int  age;
        char name[30];
    }Person;

    int PersonLess(void* _a, void* _b)
    {
        return ((Person*)_a)->age < ((Person*)_b)->age;
    }

    TreeNew(PersonLess);

                                                                                                                */
Tree* TreeNew(int(*_less)(void* _data1, void* _data2));

/*  Delete the tree contains and the tree. Deletion done in complexiabilty of O(n)).                            */
void TreeDel(Tree*);

/*  Insert data into tree.  If failed returns end iterator. Failure can cause if allocation failed              *
 *  (prints to stderr). Insert done in complexiabilty of O(log(n)).                                             */
TreeIter TreeInsert(Tree*, void* _data);

/*  Return key iterator to data in tree according to key (having the same type of data).                        *
 *  If not found return end iterator.                                                                           *
 *  Done in complexiabilty of O(log(n)).                                                                        */
TreeIter TreeFind(Tree*, void* _key);

int TreeIsEmpty(Tree*);

/*  Return data of the iterator. Remember NOT to send the end iterator for getting data.                        */
void* TreeGetData(TreeIter);

/*  Return iterator to begin of tree - The smallest in tree. If the tree empty return end iterator.             *
 *  Prev to begin is forbidden!!. Done in complexiabilty of O(1).                                              */
TreeIter TreeBegin(Tree*);

/*  Return iterator to "after" end of real data on tree. DOESN'T have real data, so don't do on it GetData.     *
 *  Don't propogate with Next. The prev of the end iterator is the the biggest in tree.                         *
 *  Done in complexiabilty of O(1).                                                                             */
TreeIter TreeEnd(Tree*);

/*  Return the next iterator of the given iterator. Not defined result doing next on end iterator!!             *
 *  Done in complexiabilty of O(log(n)).                                                                        */
TreeIter TreeNext(TreeIter);

/*  Return the prev iterator of the given iterator. Not defined result doing prev on begin iterator!!           *
 *  Done in complexiabilty of O(log(n)).                                                                        */
TreeIter TreePrev(TreeIter);

/*   Remove data from tree acording to iterator given. Return an iterator to next item. Removing end iterator	*
 *   is forbidden. Invalidates all existing iterators (except of the returning).        	                    *
 *   Done in complexiabilty of O(log(n)).                                                                       */
TreeIter TreeRemove(Tree* , TreeIter);

/*  Comapre between 2 iterators. If equal return 1, else 0.                                                     */
int TreeIsEqual(TreeIter _iter1, TreeIter _iter2);


#endif /* __TREE_H__    */
